package quenue;

import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/*
ArrayBlockingQueue ：是一个基于数组的有界阻塞队列，此队列按照FIFO（先进先出）的原则对元素进行排序。
LinkedBlockQueue:是一个基于链表结果的阻塞队列，此队列按照FIFO（先进先出）排序元素，
吞吐量通常高于ArrayBlockQueue
SynchronousQueue 一个不存储元素的阻塞队列，每个插入操作必须等到另一个线程调用移除后操作，否则插入操作一直处于阻塞状态，
吞吐量通常要高于

队列：

阻塞队列：阻塞队列是一个队列，遵循队列的特点
当阻塞队列为空时，从队列中获取元素的操作被阻塞
当队列满的时候，往队列中添加元素的操作被阻塞。
1、阻塞队列的优点

2、不得不阻塞，阻塞队列的管理


优点：我们不需要去考虑什么阻塞线程，什么时候唤醒线程，阻塞队列都替我们做好了。
简化的多线程编程
例如：生产者消费者模型
线程池
消息中间件

阻塞队列的核心架构：
Collection接口-》Queue接口-》BlockingQueue接口
BlockingQueue接口的实现类
6、ArrayBlockingQueue:由数组结构组成的有界阻塞队列
4、SynchronousQueue:不存储元素的阻塞队列，即单个元素的队列
2、LinkedBlockingQueue:由链表结构组成的有界（但大小默认为Integer.MAX_VALUE）阻塞队列

1、LinkedTransferQueue:由链表结构构成的无界阻塞队列
3、PriorityBlockingQueue:支持优先级排序的无解阻塞队列
5、DelayQueue:使用优先级队列实现的延迟无界的阻塞队列
7、LinkedBlockingDeque:由链表结构组成的双向阻塞队列

常用方法：    抛出异常       特殊值         阻塞              超时
插入          add(e)          offer(e)     put(e)         offer(e,time,unit)
移除          remove()        poll()      take()           poll(time,unit)
检查          element()       peek()        不可用           不可用

抛出异常：当阻塞队列满时，再往队列里面add插入元素会抛出IllegalStateException：Queue full
        当队列为空时，再往队列remove()移除元素时会抛出NoSuchElementException
特殊值   插入方法成功true失败false
        移除方法，成功返回出队列的元素，队列为空时候返回null

一直阻塞  当阻塞队列满时。生产者线程继续往队列里面put元素，队列会一直阻塞生产线程，
直到put数据或者响应中断退出
当阻塞队列为空时，消费者线程试图从队列中take元素，对列会一直阻塞消费者线程直到队列可用。

 */
public class BlockingQueueDemo {

    public static void main(String[] args)  throws Exception {

        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.add("a"));//true
        System.out.println(blockingQueue.add("b"));//true
        System.out.println(blockingQueue.add("c"));//true
        //Exception in thread "main" java.lang.IllegalStateException: Queue full
        //System.out.println(blockingQueue.add("D"));

        /*System.out.println(blockingQueue.remove());//a
        System.out.println(blockingQueue.remove());//b
        System.out.println(blockingQueue.remove());//c
        //Exception in thread "main" java.util.NoSuchElementException
        System.out.println(blockingQueue.remove());*/
        //判断队列是否为空，返回对头元素
        //System.out.println(blockingQueue.element());//a
        //演示offer(e)插入元素 poll()移除元素 peek()检查
        /*System.out.println(blockingQueue.offer("1111"));//false
        System.out.println(blockingQueue.offer("2222"));//false

        System.out.println(blockingQueue.poll());//a
        System.out.println(blockingQueue.poll());//b
        System.out.println(blockingQueue.poll());//c

        System.out.println(blockingQueue.poll());//null

        System.out.println(blockingQueue.peek());//null*/

        /*blockingQueue.put("ddd");//一直阻塞在这里
        blockingQueue.put("eeee");
        System.out.println("移除元素前打印：" + blockingQueue);
        blockingQueue.take();
        System.out.println("移除元素后打印" + blockingQueue);*/


    }
}
